package com.surfilter.geet.code;

//import com.surfilter.browser.Browser;
//import com.surfilter.browser.BrowserConfig;
//import com.surfilter.browser.driver.PhantomJsBrowser;
//import com.surfilter.geet.RamdomUtil;
//import com.surfilter.geet.StringParseUtils;

import com.surfilter.geet.RamdomUtil;
import com.surfilter.geet.StringParseUtils;
import com.surfilter.gsxt.util.FileWriteUtils;
import com.surfilter.gsxt.util.WebCrawlUtils;
import com.surfilter.pojo.Coordinate;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.RemoteWebElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.awt.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.ResourceBundle;
import java.util.UUID;

public class GeetestCode {

    private static Logger logger = LoggerFactory.getLogger(GeetestCode.class);

    private static String gee_screen_img_path = ResourceBundle.getBundle("collect-config").getString("gee_screen_img_path");
    private static String gee_code_slider_selector = ResourceBundle.getBundle("collect-config").getString("gee_code_slider_selector");
    private static String gee_code_fullbgslice_selector = ResourceBundle.getBundle("collect-config").getString("gee_code_fullbgslice_selector");
    private static String gee_code_bgslice_selector = ResourceBundle.getBundle("collect-config").getString("gee_code_bgslice_selector");
    private static String gee_code_success_selector = ResourceBundle.getBundle("collect-config").getString("gee_code_success_selector");
    private static String gee_xpath = ResourceBundle.getBundle("collect-config").getString("gee_xpath");

    public static boolean geeCodePass(WebCrawlUtils utils) {
        boolean target;
        int num = 0;
        while (true) {
            boolean flag = geeExist(utils);
            if(flag){
                //存在极验的元素
                logger.info("极验验证码第" + num + "次验证:start");
                target = validateGeetest(utils);
                num++;
                logger.info("验证结果:" + target);
                if (target)
                    break;
                else if (num > 5) {
                    logger.info("超过 " + num + "次验证失败，停止验证");
                    return false;
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    logger.error("极验验证码异常：" + e);
                }
            }else{
                //不存在极验元素
                target = false;
                break;
            }
        }
        return target;
    }

    private static boolean geeExist(WebCrawlUtils utils) {
        return null != utils.findElementByXpath(gee_xpath);
    }

    public static boolean validateGeetest(WebCrawlUtils utils) {

        //增加唯一标识，避免多线程的冲突
        String uuid = UUID.randomUUID().toString();

        try {
            RemoteWebElement remoteEle;
            boolean target = false;
            WebElement ele = utils.findElementByCssSelector(gee_code_slider_selector);
            if (ele == null)
                return target;
            if (ele instanceof RemoteWebElement) {
                remoteEle = (RemoteWebElement) ele;
            } else {
                return target;
            }
            logger.info("成功获取验证码滑块元素");
            WebElement imageEle = utils.findElementByCssSelector(gee_code_fullbgslice_selector);
            if (imageEle == null)
                return target;
            String regex = "http://.*\\.jpg";
            String url1 = imageEle.getAttribute("style");
            url1 = StringParseUtils.parseString(url1, regex, false);
            WebElement imagebgEle = utils.findElementByCssSelector(gee_code_bgslice_selector);
            if (imagebgEle == null)
                return target;
            logger.info("成功获取验证码图片元素");
            String url2 = imagebgEle.getAttribute("style");
            url2 = StringParseUtils.parseString(url2, regex, false);
            int length = 0;
            try {
                length = GeetestImage.getMoveLength(url1, url2, uuid);
            } catch (Exception e) {
                logger.error("移动滑块异常：" + e);
            }
            if (length == 0)
                return target;
            utils.getMouse().mouseMove(remoteEle.getCoordinates());
            File file = new File(gee_screen_img_path+"/"+uuid+"/");
            if (!file.exists()) file.mkdirs();
//            saveImageTest(utils.getDriver(), gee_screen_img_path +"/"+uuid+"/"+ "check_before.jpg");
            Thread.sleep(500);
            utils.getMouse().mouseDown(remoteEle.getCoordinates());
//            saveImageTest(utils.getDriver(), gee_screen_img_path +"/"+uuid+"/"+ "check_down.jpg");
            Thread.sleep(RamdomUtil.getRandomNum(50, 100));

            String os = System.getProperty("os.name").toLowerCase();
            List<Coordinate> points = null;
            if(os.contains("windows")){
                moveRemoteWebElementWindows(utils.getDriver(), length - 29);
            }else if(os.contains("linux")){
                moveRemoteWebElementLinux(utils.getDriver(), length - 29);
            }else{
                moveRemoteWebElementWindows(utils.getDriver(), length - 29);
            }
            Thread.sleep(RamdomUtil.getRandomNum(50, 200));
//            saveImageTest(utils.getDriver(), gee_screen_img_path +"/"+uuid+"/"+ "check_move.jpg");
            utils.getMouse().mouseUp(remoteEle.getCoordinates());
            Thread.sleep(RamdomUtil.getRandomNum(500, 800));
            saveImageTest(utils.getDriver(), gee_screen_img_path +"/"+uuid+"/"+ "check_up.jpg");
            Thread.sleep(4000);
            //判断是否存在极验验证模块，不存在表示成功
            target = !geeExist(utils);
//            WebElement success = utils.getDriver().findElementByXPath("//div[@class='gt_slider']/div[@class='gt_ajax_tip gt_success']");
//            WebElement success = utils.getDriver().findElementByXPath("//div[@class='gt_ajax_tip gt_success']");
//            WebElement success = phantomJSDriver.findElementByXPath("//div[@class='gt_slider']/div[@class='gt_ajax_tip gt_success']");
//            WebElement success = browser.selectElement(gee_code_success_selector);
//            target = success != null;
            if(target){
                FileWriteUtils.writeListToFileByLine(points,"C:/opt/rzx/point","success");
            }else{
                FileWriteUtils.writeListToFileByLine(points,"C:/opt/rzx/point","failure");
            }
            return target;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 存储验证码图片
     *
     * @param driver
     * @param filePath
     */
    public static void saveImageTest(PhantomJSDriver driver, String filePath) {
        logger.info("开始保存验证码图片: " + filePath);
        File destFile = new File(filePath);
        if (destFile.exists())
            destFile.delete();
        File sourceFile = driver.getScreenshotAs(OutputType.FILE);
        sourceFile.renameTo(new File(filePath));
    }

    /**
     * 生成网页快照
     *
     * @param file_path
     * @throws Exception
     */
    public static void geneScreenShot(PhantomJSDriver driver, String file_path) throws Exception {
        logger.info("开始生成网页快照: " + file_path);
        File file = new File(file_path);
        byte[] screenshot = driver.getScreenshotAs(OutputType.BYTES);
//        byte[] screenshot = browser.getScreenshot();
        try (OutputStream os = new FileOutputStream(file)) {
            os.write(screenshot);
            os.close();
        }
    }

    public static void moveRemoteWebElementLinux(PhantomJSDriver driver, int length){
//        int px = MouseInfo.getPointerInfo().getLocation().x;
//        int py = MouseInfo.getPointerInfo().getLocation().y;
        Robot robot = null;
        try {
            robot = new Robot();
        } catch (AWTException e) {
            e.printStackTrace();
        }
        long start = System.currentTimeMillis();
        long end = start;
        try{
            int sum = 0;
            int max = 18;
            int min = 5;
            int sleep_max = 500;
            int sleep_min = 100;
            while(true){
                int subLength = RamdomUtil.getRandomNum(min, max);
                int x = 0;
                int y = RamdomUtil.getRandomNum(-1, 2);
                if(sum + subLength > length){
                    x = length - sum;
                }else{
                    x = subLength;
                }
                driver.getMouse().mouseMove(null, x, y);
//                px += x;
//                py += y;
//                robot.mouseMove(px, py);
                sum += subLength;
                if(sum >= length)break;
                Thread.sleep(RamdomUtil.getRandomNum(sleep_min, sleep_max));
                if(length - sum < 50){
                    max = 4;
                    min = -1;
                    sleep_min = 10;
                    sleep_max = 45;
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        end = System.currentTimeMillis();
        System.out.println("移动鼠标耗时:" + (end - start));
    }

    public static void moveRemoteWebElementWindows(PhantomJSDriver driver, int length){
//        Robot robot = null;
//        try {
//            robot = new Robot();
//        } catch (AWTException e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        }
//        int px = MouseInfo.getPointerInfo().getLocation().x;
//        int py = MouseInfo.getPointerInfo().getLocation().y;
        long start = System.currentTimeMillis();
        long end = start;
        try{
            int sum = 0;
            int max = 10;
            int min = 5;
            int sleep_max = 300;
            int sleep_min = 50;
            while(true){
                int subLength = RamdomUtil.getRandomNum(min, max);
                int x = 0;
                int y = RamdomUtil.getRandomNum(-3, 2);
                if(sum + subLength > length){
                    x = length - sum;
                }else{
                    x = subLength;
                }
                driver.getMouse().mouseMove(null, x, y);
//                px += x;
//                py += y;
//                robot.mouseMove(px, py);
                sum += subLength;
                if(sum >= length)break;
                Thread.sleep(RamdomUtil.getRandomNum(sleep_min, sleep_max));
                if(length - sum < 15){
                    max = 4;
                    min = -2;
                    sleep_min = 50;
                    sleep_max = 100;
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        end = System.currentTimeMillis();
        System.out.println("移动鼠标耗时:" + (end - start));
    }


    /**
     * 移动验证码滑块
     *
     * @param driver
     * @param length
     */
    public static void moveRemoteWebEle(RemoteWebDriver driver, int length) {
        logger.info("开始移动验证码滑块元素");
        long start = System.currentTimeMillis();
        long end;
        try {
            int sum = 0;
            while (true) {
                int subLength = RamdomUtil.getRandomNum(1, 4);
                if (sum + subLength > length) {
                    driver.getMouse().mouseMove(null, length - sum, RamdomUtil.getRandomNum(-2, 0));
                } else {
                    driver.getMouse().mouseMove(null, subLength, RamdomUtil.getRandomNum(-2, 0));
                }
                sum += subLength;
                if (sum >= length)
                    break;
                Thread.sleep(RamdomUtil.getRandomNum(20, 50));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        end = System.currentTimeMillis();
        logger.info("滑块移动结束,移动鼠标耗时:" + (end - start));
    }


//    public static void main(String[] args) throws Exception {
//
//        Browser browser = new PhantomJsBrowser();
//        browser.open("http://www.geetest.com/exp_embed");
//        Thread.sleep(3000);
////        WebElement userInput = browser.selectElement("input[name='account']");
////        WebElement passwdInput = browser.selectElement("input[name='password']");
////        WebElement loginBtn = browser.selectElement("#btnLogin");
////        userInput.sendKeys("18612394360");
////        passwdInput.sendKeys("nike519649867");
//        boolean is_check = geeCodePass(browser);
//        if (is_check) {
////            loginBtn.click();
//            Thread.sleep(10000);
//            geneScreenShot(browser, gee_screen_img_path + "snapshot.jpg");
////            WebElement logo = browser.selectElement("body > div.top-section > div > div.slogan");
////            System.out.println("登录成功,logo内容:" + logo.getText());
//        }
//        browser.close();
//    }
//
//    public void test(){
//        BrowserConfig config = new BrowserConfig();
//        config.setJsEnable(true);
//        config.setImgEnable(true);
//        Browser browser = new PhantomJsBrowser(config);
//
//        RemoteWebDriver driver = (RemoteWebDriver) browser.getDriver();
//        for(int i=0;i<10;i++){
//            driver.getMouse().mouseMove(null,1+i,1+i);
//            try {
//                Thread.sleep(500);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }
//
//         new Thread(new Runnable() {
//             @Override
//             public void run() {
//                 BrowserConfig config = new BrowserConfig();
//                 config.setJsEnable(true);
//                 config.setImgEnable(true);
//                 Browser browser = new PhantomJsBrowser(config);
//
//                 RemoteWebDriver driver = (RemoteWebDriver) browser.getDriver();
//                 for(int j=0;j<10;j++){
//                     driver.getMouse().mouseMove(null,1+j,1+j);
//                     try {
//                         Thread.sleep(500);
//                     } catch (InterruptedException e) {
//                         e.printStackTrace();
//                     }
//                 }
//             }
//         }).start();
//
//    }

}
